﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;
using Pavilion.DesignerTool.ViewTools;
using Pavilion.DesignerTool.ViewTools.ConnectableListBox;

namespace Pavilion.DesignerTool
{
    /// <summary>
    /// Interaction logic for NodeDesignerToolView.xaml
    /// </summary>
    public partial class NodeDesignerToolView : UserControl
    {
        private NodeDesignerToolViewModel viewModel;
        public NodeDesignerToolViewModel ViewModel
        {
            get { return viewModel; }
            private set
            {
                viewModel = value;
                DataContext = viewModel;
            }
        }

        public NodeDesignerToolView()
        {
            this.ViewModel = new NodeDesignerToolViewModel();
            InitializeComponent();
        }

        public void LoadResourceItem(AnimationResourceData animationResourceData)
        {
            ViewModel.LoadResourceItem(animationResourceData);
            gameDataEditorView.LoadResource(animationResourceData);

            connectableListBox.ArrangeChildrenInRows();
        }

        private void ListBoxItemDragging(object sender, RoutedEventArgs e)
        {
            DragAwareListBoxItem draggingListBox = e.OriginalSource as DragAwareListBoxItem;

            if (draggingListBox != null)
                draggingListBox.RespondToDrag();
        }

        private void LoadGameDataEditor(NodeBaseWrapper nodeWrapper)
        {
            gameDataEditorView.SetGameData(nodeWrapper);

            if (propertiesPanel.Visibility == Visibility.Visible && lockEditorView.Visibility != Visibility.Collapsed)
            {
                lockEditorView.Visibility = Visibility.Collapsed;
                gameDataEditorView.Visibility = Visibility.Visible;
            }
        }

        private void LoadLinkEditor(LinkWrapper linkWrapper)
        {
            lockEditorView.SetLink(linkWrapper);

            if (propertiesPanel.Visibility == Visibility.Visible && gameDataEditorView.Visibility != Visibility.Collapsed)
            {
                lockEditorView.Visibility = Visibility.Visible;
                gameDataEditorView.Visibility = Visibility.Collapsed;
            }
        }

        private void StepIntoMenuItem_Click(object sender, RoutedEventArgs e)
        {
            ViewModel.StepIntoNode(connectableListBox.SelectedConnectableItem);
        }

        private void StepOut_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ViewModel != null ? ViewModel.CanStepOut : false;
        }

        private void StepOut_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.StepOutOfNode();
        }

        private void PropertiesButton_Click(object sender, RoutedEventArgs e)
        {
            if ((sender as ToggleButton).IsChecked == true)
                propertiesPanel.Visibility = Visibility.Visible;
            else
                propertiesPanel.Visibility = Visibility.Collapsed;
        }

        private void NewAnimationNode(object sender, RoutedEventArgs e)
        {
            ViewModel.AddNewAnimationNode();
        }

        private void NewContainerNode(object sender, RoutedEventArgs e)
        {
            ViewModel.AddNewContainerNode();
        }

        //refactor
        private void listBox_ConnectionPending(object sender, RoutedEventArgs e)
        {
            var eventArgs = e as ConnectionPendingRoutedEventArgs;

            NodeBaseWrapper startNode = eventArgs.Start.DataContext as NodeBaseWrapper;
            NodeBaseWrapper endNode = eventArgs.End.DataContext as NodeBaseWrapper;

            ViewModel.AddLink(startNode, endNode);
        }

        private void ListBoxItem_IsDragging(object sender, RoutedEventArgs e)
        {
            ItemDraggedRoutedEventArgs eventArgs = e as ItemDraggedRoutedEventArgs;
            Grid anchorGrid = null;

            VisualTreeWalker walker = new VisualTreeWalker();
            walker.VisualVisited += (s, args) =>
            {
                if (args.VisitedVisual is Grid)
                {
                    Grid grid = args.VisitedVisual as Grid;
                    if (grid.Name.Equals("anchorGrid"))
                        anchorGrid = grid;
                }
            };
            walker.Walk(eventArgs.ElementBeingDragged);

            double x = Canvas.GetLeft(anchorGrid);
            double y = Canvas.GetTop(anchorGrid);

            TransformGroup transformGroup = new TransformGroup();
            transformGroup.Children.Add(new TranslateTransform(eventArgs.LocationDraggedTo.X, eventArgs.LocationDraggedTo.Y));
            anchorGrid.RenderTransform = transformGroup;
        }

        private void anchorGrid_IsDragging(object sender, RoutedEventArgs e)
        {
            ItemDraggedRoutedEventArgs eventArgs = e as ItemDraggedRoutedEventArgs;
            Grid anchorGrid = null;

            VisualTreeWalker walker = new VisualTreeWalker();
            walker.VisualVisited += (s, args) =>
            {
                if (args.VisitedVisual is Grid)
                {
                    Grid grid = args.VisitedVisual as Grid;
                    if (grid.Name.Equals("anchorGrid"))
                        anchorGrid = grid;
                }
            };
            walker.Walk(eventArgs.ElementBeingDragged);

            double x = Canvas.GetLeft(anchorGrid);
            double y = Canvas.GetTop(anchorGrid);

            TransformGroup transformGroup = new TransformGroup();
            transformGroup.Children.Add(new TranslateTransform(eventArgs.LocationDraggedTo.X, eventArgs.LocationDraggedTo.Y));
            anchorGrid.RenderTransform = transformGroup;
        }

        private void ConnectableListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (connectableListBox.SelectedItem == null)
            {
                gameDataEditorView.SetGameData(null);
                lockEditorView.SetLink(null);
            }
        }

        private void RemoveLink_MenuItemClick(object sender, RoutedEventArgs e)
        {
            viewModel.RemoveLink(connectableListBox.SelectedItem as LinkWrapper);
        }

        private void RemoveMenuItem_Click(object sender, RoutedEventArgs e)
        {
            ViewModel.RemoveNode(connectableListBox.SelectedItem as NodeBaseWrapper);
        }

        private void ConnectableListBox_ConnectonatorSelected(object sender, RoutedEventArgs e)
        {
            LoadLinkEditor(connectableListBox.SelectedConnectonator as LinkWrapper);
        }

        private void ConnectableListBox_ConnectableItemSelected(object sender, RoutedEventArgs e)
        {
            LoadGameDataEditor(connectableListBox.SelectedItem as NodeBaseWrapper);
        }

        private void NodeItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            ViewModel.StepIntoNode(connectableListBox.SelectedConnectableItem);
        }
    }
}
